package cn.taobaoke.restful.controller;

import cn.taobaoke.restful.datasource.TargetDataSource;
import cn.taobaoke.restful.domain.AgentEntity;
import cn.taobaoke.restful.domain.PIDEntity;
import cn.taobaoke.restful.domain.ProductEntity;
import cn.taobaoke.restful.exception.TBKException;
import cn.taobaoke.restful.service.*;
import cn.taobaoke.restful.util.Constants;
import cn.taobaoke.restful.util.GsonUtil;
import cn.taobaoke.restful.util.OkHttpUtil;
import cn.taobaoke.restful.util.ProductUtil;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.*;

/**
 * ProductController类.
 * +-----------------------------------------------------------------------------------------------+
 * |类名称: ProductController                                                                       |
 * |创建时间: 3/17/17                                                                               |
 * |功能简介:                                                                                       |
 * |参考链接:                                                                                       |
 * +-----------------------------------------------------------------------------------------------+
 *
 * @author luch
 */
@RestController
@RequestMapping(value = "/{domain}/{domainId}/api/products")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ProductController extends BaseController {

    public static final Integer SIZE = 100;

    // 商品中心接口
    private static final String PRODUCT_HOST = "http://47.93.227.191:8181";
    private static String DEFAULT_COUPON_URL = "http://yhq.gittis.co";
    private static final String SHORT_SERVER_HOST = "http://47.93.227.191:8181";

//    http://47.93.227.191:8181/cwl/search/count?keyword=袜子&nsukey=NXB3f2m9FbFKU4VrJGevBw%2FJCr0VR34GickxIBjRCM69%2F2k56x0yIhYE22tcW1DM0U01J9jsBKn0rGJh8m%2FoBXvg5ZBk8waZZpAy23PMg13%2BznJSB9lHOhLonHJmAyU0MPdHOhwmFvPbBWmXk5fX1L98NYoXXTyFwlJDpDlzEXnakvPI5PeRefupWYJavY9E

    //    Doc
    @GetMapping("/count")
    public String getProductCount(@PathVariable Long domainId, String keyword) throws IOException {
        keyword = keyword == null ? "" : keyword;
        String countAPI = String.format("%s/cwl/search/count?keyword=%s", PRODUCT_HOST, keyword);
        return OkHttpUtil.DEFAULT.get(countAPI);
    }


    /**
     * 返回查询数量与详情地址
     *
     * @param domain
     * @param identity
     * @param keyword
     * @return
     * @throws IOException
     */
    @GetMapping("/countWithShortLink")
    public Result searchProductCountWithShortLink(@PathVariable String domain, String identity, String keyword) throws IOException {
        String items[] = identity.split("_");
        //        wx_c008_1_default
        if (items.length != 4) {
            throw new TBKException("非法格式的identity");
        }
        String agentIdStr = items[2];

        String countAPI = String.format("%s/cwl/search/count?keyword=%s", PRODUCT_HOST, keyword);
        String ret = OkHttpUtil.DEFAULT.get(countAPI);
        if (ret == null || ret.trim().isEmpty()) {
            throw new TBKException("查询失败");
        }
        Map map = GsonUtil.getObject(ret);
        Boolean success = (Boolean) map.get("success");
        if (success == null || !success) {
            throw new TBKException((String) map.get("message"));
        }
        Double countDbl = (Double) map.get("data");


        String detailUrl = String.format("%s/#/search/%s/d/%s/p/%s/#", DEFAULT_COUPON_URL, keyword, domain, agentIdStr);
        String shortLink = innerAPIService.shortLink(detailUrl);

        Map resultMap = new HashMap();
        resultMap.put("count", countDbl.intValue());
        resultMap.put("detailLink", shortLink);
        return wrapObj(resultMap);
    }


    //    @TargetDataSource
    @GetMapping("")
    public Result search(@PathVariable Long domainId, String keywords, Integer pageSize, Integer page) {
        logger.debug("GET /{}/api/products?keywords={}&pageSize={}&page={}", domainId, keywords, pageSize, page);

        Pageable pageable = createPageable(page, pageSize, "sourceNo", "desc");

        List<String> keywordList = new ArrayList<>(0);
        if (keywords != null) {
            keywordList = Arrays.asList(keywords.split("(,| |;|，)"));
        }
        logger.info("keywords size => {}, keyword => {}", keywordList.size(), keywordList);
        Page<ProductEntity> productEntityPage = productService.search(keywordList, pageable, domainId);

        logger.info("查询结果: {}", productEntityPage);

        return wrapPage(pageable, productEntityPage);
    }

    @GetMapping("/prods")
    public Result getSendProducts(@PathVariable String domain, Integer agentId, String startId, Integer size, String keyword, String type, String price) {
        size = (size == null ? 10 : size);
        String url = "http://47.93.227.191:8181/cwl/search/internal?startid=" + startId + "&size=" + size + "&keyword=" + (keyword == null ? "" : keyword) + "&type=" + (type == null ? "" : type) + "&price=" + (price == null ? "" : price);
        url = url + "&pid=" + domain;
        if (agentId != null) {
            url = url + "&sid=" + agentId;
        }

        RestTemplate restTemplate = new RestTemplate();
        String jsonStr = restTemplate.getForEntity(url, String.class).getBody();
        JsonObject json = new JsonParser().parse(jsonStr).getAsJsonObject();

        JsonArray array = json.get("data").getAsJsonArray();

        int len = array.size();
        List<ProductEntity> result = new ArrayList<>();
        for (int i = 0; i < len; i++) {
            ProductEntity entity = new ProductEntity();
            JsonObject obj = array.get(i).getAsJsonObject();

            entity.setItemId(obj.get("itemid").getAsString());
            entity.setId(obj.get("id").getAsLong());
            entity.setItemImage(obj.get("pic").getAsString());
            entity.setItemName(obj.get("title").getAsString());
            entity.setCouponLink(obj.get("couponUrl").getAsString());
            entity.setTaobaoUrl(obj.get("taobaoUrl").getAsString());
            if (obj.has("choosedOrNot")) {
                entity.setChoosedOrNot(obj.get("choosedOrNot").getAsBoolean());
            }

            entity.setIntro("");
            if (obj.has("couponDesc")) {
                entity.setIntro(obj.get("couponDesc").getAsString());
            }
            entity.setItemRate(-1);
            if (obj.has("commissionRate")) {
                entity.setItemRate(Double.valueOf(obj.get("commissionRate").getAsString()).intValue());
            }

            double oldPrice = obj.get("oldPrice").getAsDouble();
            double newPrice = obj.get("newPrice").getAsDouble();

            entity.setItemPrice(oldPrice);
            entity.setCouponAmount(oldPrice - newPrice);

            result.add(entity);
        }

        return wrapObj(result);
    }

    @GetMapping("/prods/page")
    public Result getPagingProducts(@PathVariable String domain, Integer agentId, String pnum, String size, String keyword, String price, String sprice, String orderby, String sort) {

        pnum = (pnum == null ? "" : pnum);
        size = (size == null ? "" : size);
        keyword = (keyword == null ? "" : keyword);
        price = (price == null ? "" : price);
        sprice = (sprice == null ? "" : sprice);
        orderby = (orderby == null ? "" : orderby);
        sort = (sort == null ? "" : sort);

        String url = "http://47.93.227.191:8181/cwl/search/sort?pnum=" + pnum + "&size=" + size + "&keyword=" + keyword + "&price=" + price + "&sprice=" + sprice + "&orderby=" + orderby + "&sort=" + sort;
        url = url + "&pid=" + domain;
        if (agentId != null) {
            url = url + "&sid=" + agentId;
        }

        RestTemplate restTemplate = new RestTemplate();
        String jsonStr = restTemplate.getForEntity(url, String.class).getBody();
        JsonObject json = new JsonParser().parse(jsonStr).getAsJsonObject();

        JsonArray array = json.get("data").getAsJsonArray();
        int len = array.size();
        List<ProductEntity> result = new ArrayList<>();
        for (int i = 0; i < len; i++) {
            JsonObject obj = array.get(i).getAsJsonObject();
            ProductEntity entity = new ProductEntity();

            entity.setItemId(obj.get("itemid").getAsString());
            entity.setId(obj.get("id").getAsLong());
            entity.setItemImage(obj.get("pic").getAsString());
            entity.setItemName(obj.get("title").getAsString());
            entity.setCouponLink(obj.get("couponUrl").getAsString());
            entity.setTaobaoUrl(obj.get("taobaoUrl").getAsString());
            entity.setMonthSale(obj.get("monthSale").getAsInt());
            if (obj.has("choosedOrNot")) {
                entity.setChoosedOrNot(obj.get("choosedOrNot").getAsBoolean());
            }

            entity.setIntro("");
            if (obj.has("couponDesc")) {
                entity.setIntro(obj.get("couponDesc").getAsString());
            }
            entity.setItemRate(-1);
            if (obj.has("commissionRate")) {
                entity.setItemRate(Double.valueOf(obj.get("commissionRate").getAsString()).intValue());
            }

            double oldPrice = obj.get("oldPrice").getAsDouble();
            double newPrice = obj.get("newPrice").getAsDouble();

            entity.setItemPrice(oldPrice);
            entity.setCouponAmount(oldPrice - newPrice);

            result.add(entity);
        }

        return wrapObj(result);
    }

    @GetMapping("/prods/getitem")
    public Result getItemProducts(String id) {
        String url = "http://47.93.227.191:8181/cwl/search/getitem?id=" + (id == null ? "" : id);
        RestTemplate restTemplate = new RestTemplate();
        String jsonStr = restTemplate.getForEntity(url, String.class).getBody();
        JsonObject json = new JsonParser().parse(jsonStr).getAsJsonObject();

        if (!json.get("success").getAsBoolean()) {
            throw new TBKException("Failed to query product information.");
        }

        Map<String, Object> data = new HashMap<>();
        if (json.get("data").isJsonObject()) {
            JsonObject obj = json.get("data").getAsJsonObject();

            data.put("title", obj.get("title").getAsString());
            data.put("taobaoUrl", obj.get("taobaoUrl").getAsString());
            data.put("pic", obj.get("pic").getAsString());
            data.put("oldPrice", obj.get("oldPrice").getAsDouble());
            data.put("newPrice", obj.get("newPrice").getAsDouble());
            data.put("monthSale", obj.get("monthSale").getAsInt());
            data.put("itemid", obj.get("itemid").getAsString());
            data.put("id", obj.get("id").getAsString());
            data.put("description", obj.get("description").getAsString());
            data.put("couponUrl", obj.get("couponUrl").getAsString());
            data.put("couponMoney", obj.get("couponMoney").getAsDouble());
            data.put("couponJsonUrl", obj.get("couponJsonUrl").getAsString());
            data.put("couponDesc", obj.get("couponDesc").getAsString());

            if (obj.get("commissionType") != null) {
                data.put("commissionType", obj.get("commissionType").getAsString());
            }
            if (obj.get("commissionRate") != null) {
                data.put("commissionRate", obj.get("commissionRate").getAsDouble());
            }

            data.put("etime", obj.get("etime").getAsString());
            data.put("stime", obj.get("stime").getAsString());
        }

        if (json.get(("imgs")) != null) {
            JsonArray array = json.get("imgs").getAsJsonArray();
            List<String> imgs = new ArrayList<>();
            for (int i = 0; i < array.size(); i++) {
                imgs.add(array.get(i).getAsString());
            }
            data.put("imgs", imgs);
        }

        return wrapObj(data);
    }

    @PostMapping("/lowvalue")
    public Result setLowValueStatus(@RequestBody Map map) {
        String id = map.get("id").toString();
        String status = map.get("status").toString();

        RestTemplate restTemplate = new RestTemplate();
        String url = "http://47.93.227.191:8181/cwl/update/itemstatus";
        MultiValueMap requestParams = new LinkedMultiValueMap();
        requestParams.add("id", id);
        requestParams.add("status", status);

        String response = restTemplate.postForEntity(url, requestParams, String.class).getBody();

        return wrapObj(response);
    }

    //    @TargetDataSource
    @GetMapping("/limit")
    public Result queryProductsLimitN(@PathVariable Long domainId, Integer id, Integer size) {
        logger.debug("GET /{}/api/products/limit?id={}&size={}", domainId, id, size);

        if (size == null) {
            size = SIZE;
        }

        List<ProductEntity> list = productService.findLimitN(id, size, domainId);
        return wrapObj(list);
    }

    //    @TargetDataSource
    @PutMapping("")
    public Result saveProduct(@PathVariable Long domainId, @RequestBody ProductEntity productEntity) {
        logger.debug("PUT /{}/api/products", domainId);

        productService.createOrUpdate(productEntity, domainId);
        return wrapVoid();
    }

    //    @TargetDataSource
    @PutMapping("/list")
    public Result saveProductList(@PathVariable Long domainId, @RequestBody List<ProductEntity> productEntityList) {
        logger.debug("PUT /{}/api/products/list", domainId);

        productService.createOrUpdate(productEntityList, domainId);
        return wrapVoid();
    }

    // 获取淘口令相关推广链接
    // TODO 批量处理多个
//    @TargetDataSource
    @PostMapping("/{itemId}/exchangeTkl")
    public Result exchangeTaobaoToken(@PathVariable String domain, @PathVariable String itemId) {
        logger.debug("POST /{}/api/products", domain);

        // TODO 等待欣爷那边介入该接口
        // 发单特定商品转链
        return wrapVoid();
    }


    /**
     * 发单机器人,获取商品接口(会自动记录每次的位置)
     *
     * @param identity
     * @param size
     * @return
     * @throws IOException
     * @doc https://tower.im/projects/2ba7c224598f43e0b511141508649834/docs/70bd74b4661543769a1bf00077c10b43/
     */
    @GetMapping("/forRobot")
    public Result getRobotSendProduct(@RequestParam String identity, Integer size) throws IOException {
        String senderProductApi = String.format("%s/cwl/goods/send?identity=%s&size=%d", PRODUCT_HOST, identity, size);
        Map param = new HashMap();
        param.put("size", size);
        param.put("robotid", identity);
        String ret = OkHttpUtil.DEFAULT.postJson(senderProductApi, GsonUtil.getJsonString(param));
        List<ProductEntity> products = parseProductRetList(ret);
        return wrapObj(products);
    }


    /**
     * 获取APP发单机器人的发单消息
     *
     * @param identity
     * @param size
     * @return
     */
    @GetMapping("/forMobileRobot")
    @TargetDataSource
    public Result getMobileProduct(@PathVariable String domain, @PathVariable Long domainId, String identity, Integer size) throws IOException {
        String senderProductApi = String.format("%s/cwl/goods/send?identity=%s&size=%d", PRODUCT_HOST, identity, size);
        Map param = new HashMap();
        param.put("size", size);
        param.put("robotid", identity);
        String ret = OkHttpUtil.DEFAULT.postJson(senderProductApi, GsonUtil.getJsonString(param));
        return parseAndFormateProductRet(domain, domainId, identity, ret);
    }


    public Result parseAndFormateProductRet(String domain, Long domainId, String identity, String ret) throws IOException {
        List<ProductEntity> products = parseProductRetList(ret);

        Integer agentId = getAgentId(identity);
        AgentEntity agent = agentService.getAgentById(Long.valueOf(agentId), domainId);

        Map<String, Object> config = globalConfigService.queryConfig(domainId);
        String pid = (String) config.getOrDefault(cn.taobaoke.restful.util.Constants.ADMIN_PID, "");

        if (agentId != null) {
            PIDEntity pidEntity = pidService.getPidByAgentId(Long.valueOf(agentId), domainId);
            if (pidEntity == null) {
                logger.error("agentId => {} pid = is null", agentId);
            }
            if (pidEntity != null) {
                pid = pidEntity.getPid();
            }
        }

        Map map = (Map) config.get("config");
        String couponUrl = "http://yhq.gittis.co";
        if (map != null && map.containsKey("couponUrl")) {
            couponUrl = (String) map.get("couponUrl");
        }

        String template = (String) config.getOrDefault("template", Constants.PRODUCT_DEFAULT_TEMPLATE);
        logger.info("template => {}", template);

        List<Map> messages = new ArrayList<>();
        for (ProductEntity product : products) {
            logger.info("taobaoApi.getTaokoulin: Link={}", product.getCouponLink());
            String tkl = taobaoApi.getTaokoulinByCouponAndPid(domain, product.getCouponLink(), pid);
            logger.info("[POST] /{}/api/third/tkls/translateLink tkl={}", domain, tkl);

            //  http://localhost:3000/#/detail/9667227/1/test
            String detailUrl = String.format("%s/#/detail/%d/%d/%s", couponUrl, product.getId(), agentId, domain);
            String shortLink = innerAPIService.shortLink(detailUrl);

            String product_template = ProductUtil.send_product_template(template, product, tkl, shortLink);
            Map productMap = new HashMap();
            productMap.put("content", product_template);
            productMap.put("imageUrl", product.getItemImage());
            productMap.put("detailUrl", shortLink);
            productMap.put("intro", product.getIntro());
            productMap.put("price", product.getItemPrice());
            productMap.put("couponAmount", product.getCouponAmount());
            productMap.put("itemName", product.getItemName());

            if (product.getDescImgs() != null) {
                productMap.put("descImgs", product.getDescImgs());
            } else {
                productMap.put("descImgs", Arrays.asList(product.getItemImage()));
            }

            // 计算佣金, commissionRate
            if (product.getItemRate() != null) {
                // agent
                Double price = product.getItemPrice();
                Double coupon = product.getCouponAmount();
                Integer rate = product.getItemRate();

                Double couponRate = (price - coupon) * 0.85 * rate / 100;
                if (agent != null && agent.getPerOfCommission() != null) {
                    couponRate = couponRate * agent.getPerOfCommission() / 100;
                    logger.info("coupon rate => {}", couponRate);
                }
                productMap.put("itemRate", rate);
                productMap.put("commissionRate", couponRate);
            }

            productMap.put("nextTime", 55);     // next produt got time
            messages.add(productMap);
        }
        return wrapObj(messages);
    }


    public Integer getAgentId(String identity) {
        String[] items = identity.split("_");
        return Integer.valueOf(items[2]);
    }


    public List<ProductEntity> parseProductRetList(String ret) {
        Map map = GsonUtil.getObject(ret);
        if (map == null || !map.containsKey("success")) {
            throw new TBKException("request product center failed!");
        }

        Boolean success = (Boolean) map.get("success");
        if (!success) {
            throw new TBKException((String) map.get("message"));
        }

        List<Map> items = (List<Map>) map.get("data");
        List<ProductEntity> result = parseProductFromRet(items);
        return result;
    }


    private Result convertRetToResult(String ret) {
        List<ProductEntity> products = parseProductRetList(ret);
        return wrapObj(products);
    }


    private List<ProductEntity> parseProductFromRet(List<Map> items) {
        if (items == null) return Collections.EMPTY_LIST;

        List<ProductEntity> result = new ArrayList<>();
        for (int i = 0; i < items.size(); i++) {
            ProductEntity entity = new ProductEntity();
            Map itemMap = items.get(i);

            entity.setItemId((String) itemMap.get("itemid"));
            if (itemMap.containsKey("id")) {
                Double id = (Double) itemMap.get("id");
                entity.setId(id.longValue());
            }
            entity.setItemImage((String) itemMap.get("pic"));
            entity.setItemName((String) itemMap.get("title"));
            entity.setCouponLink((String) itemMap.get("couponUrl"));
            entity.setTaobaoUrl((String) itemMap.get("taobaoUrl"));

            entity.setIntro("");
            if (itemMap.containsKey("description")) {
                entity.setIntro((String) itemMap.get("description"));
            }
            entity.setItemRate(-1);
            if (itemMap.containsKey("commissionRate")) {
                Double rate = (Double) itemMap.get("commissionRate");
                entity.setItemRate(rate.intValue());
            }

            Double oldPrice = (Double) itemMap.get("oldPrice");
            Double newPrice = (Double) itemMap.get("newPrice");
            entity.setItemPrice(oldPrice);
            entity.setCouponAmount(oldPrice - newPrice);
            entity.setDescImgs((List<String>) itemMap.get("imgsArray"));
            result.add(entity);
        }
        return result;
    }


    /**
     * 修改商品佣金接口
     *
     * @param map
     * @return
     * @throws IOException
     * @doc https://tower.im/projects/2ba7c224598f43e0b511141508649834/docs/70bd74b4661543769a1bf00077c10b43/
     */
    @PostMapping("/updateCommissionRate")
    public String setProductCommissionRate(@PathVariable String domain, String alimama, @RequestBody Map map) throws IOException {
        //  id 是	商品ID
        //  crate	是	佣金
        if (map == null || !map.containsKey("crate") || !map.containsKey("id")) {
            throw new TBKException("crate, id 参数必须填写");
        }

        String rateAPI = String.format("%s/cwl/update/itemcrate", PRODUCT_HOST);
        String robotid = genIdentity(domain, null, alimama);
        map.put("robotid", robotid);
        return OkHttpUtil.DEFAULT.postJson(rateAPI, GsonUtil.getJsonString(map));
    }


    /**
     * 代理添加自己的商品库
     *
     * @param domain
     * @param agentId
     * @param productId
     * @return
     * @throws IOException
     * @doc https://tower.im/projects/2ba7c224598f43e0b511141508649834/docs/70bd74b4661543769a1bf00077c10b43/
     */
    @PostMapping("/agents/{agentId}/chooseProduct")
    public String agentChooseProduct(@PathVariable String domain, @PathVariable Integer agentId, Integer productId) throws IOException {
        String chooseAPI = String.format("%s/cwl/goods/userchoose", PRODUCT_HOST);

        Map<String, Object> param = new HashMap<>();
        param.put("id", productId);
        param.put("pid", domain);
        param.put("sid", agentId);
        return OkHttpUtil.DEFAULT.postJson(chooseAPI, GsonUtil.getJsonString(param));
    }


    /**
     * 管理员添加自己的商品
     *
     * @param domain
     * @param productId
     * @return
     * @throws IOException
     * @doc https://tower.im/projects/2ba7c224598f43e0b511141508649834/docs/70bd74b4661543769a1bf00077c10b43/
     */
    @PostMapping("/admin/chooseProduct")
    public String adminChooseProduct(@PathVariable String domain, Integer productId) throws IOException {
        String chooseAPI = String.format("%s/cwl/goods/tbkchoose", PRODUCT_HOST);

        Map<String, Object> param = new HashMap<>();
        param.put("id", productId);
        param.put("pid", domain);
        return OkHttpUtil.DEFAULT.postJson(chooseAPI, GsonUtil.getJsonString(param));
    }

    @GetMapping("/toApply")
    public String applayProductPlan(@PathVariable String domain, String alimama, Integer size) throws IOException {
        String applyAPI = String.format("%s/cwl/goods/apply", PRODUCT_HOST);

        String identity = genIdentity(domain, null, alimama);
        if (size == null) size = 20;

        Map<String, Object> param = new HashMap<>();
        param.put("robotid", identity);
        param.put("size", size);

        return OkHttpUtil.DEFAULT.postJson(applyAPI, GsonUtil.getJsonString(param));
    }

    @GetMapping("/admin/choosen")
    public Result getAdminChooseProduct(@PathVariable String domain, Integer page, Integer size) throws IOException {
        page = page == null ? 1 : page;
        size = size == null ? 20 : size;
        size = size < 0 ? 20 : size;
        size = size > 100 ? 100 : size;

        String adminChoosenAPI = String.format("%s/cwl/goods/getchoosed?pid=%s&pnum=%d&size=%d", PRODUCT_HOST, domain, page, size);
        String ret = OkHttpUtil.DEFAULT.get(adminChoosenAPI);
        return convertRetToResult(ret);
    }

    @GetMapping("/agents/{agentId}/choosen")
    public Result getAgentChooseProduct(@PathVariable String domain, @PathVariable Integer agentId, Integer page, Integer size) throws IOException {
        page = page == null ? 1 : page;
        size = size == null ? 20 : size;
        size = size < 0 ? 20 : size;
        size = size > 100 ? 100 : size;

        String agentChoosenAPI = String.format("%s/cwl/goods/getchoosed?pid=%s&sid=%d&pnum=%d&size=%d", PRODUCT_HOST, domain, agentId, page, size);
        String ret = OkHttpUtil.DEFAULT.get(agentChoosenAPI);
        return convertRetToResult(ret);
    }

    public static String genIdentity(String domain, String agentId, String robotId) {
        if (agentId == null) agentId = "default";
        if (robotId == null) robotId = "default";
        return String.format("wx_%s_%s_%s", domain, agentId, robotId);
    }


    @GetMapping("/latest/forGroup")
    public Result getLatestProductForGroup(@PathVariable String domain, @PathVariable Long domainId, Integer agentId, Integer size) throws IOException {
        size = size == null ? 20 : size;
        String senderProductApi = String.format("%s/cwl/search/sort?choose=true&size=%d", PRODUCT_HOST, size);
        agentId = (agentId != null && agentId <= 0) ? null : agentId;
        String ret = OkHttpUtil.DEFAULT.get(senderProductApi);
        return parseAndFormateProductRet2(domain, domainId, agentId, ret);
    }

    @GetMapping("/latest/fogrTimeline")
    public Result getLatestProductForTimeline(@PathVariable String domain, @PathVariable Long domainId, String identity, Integer agentId, Integer size) throws IOException {
        size = size == null ? 10 : size;
        agentId = (agentId != null && agentId <= 0) ? null : agentId;

        String timelineProductApi = String.format("%s/cwl/search/sort?pyq=true&size=%d", PRODUCT_HOST, size);
        String ret = OkHttpUtil.DEFAULT.get(timelineProductApi);
        return parseTimelineProduct(domain, domainId, agentId, ret);
    }

    //========================================
    // @add by luc
    @GetMapping("/latest/forGroup2")
    public Result getLatestProductForGroup2(@PathVariable String domain, @PathVariable Long domainId, Integer agentId, Integer size) throws IOException {
        size = size == null ? 20 : size;
        String senderProductApi = String.format("%s/cwl/search/sort?choose=true&size=%d", PRODUCT_HOST, size);
        agentId = (agentId != null && agentId <= 0) ? null : agentId;
        String ret = OkHttpUtil.DEFAULT.get(senderProductApi);
        return parseAndFormateProductRet2(domain, domainId, agentId, ret);
    }

    @GetMapping("/latest/forTimeline2")
    public Result getLatestProductForTimeline2(@PathVariable String domain, @PathVariable Long domainId, Integer agentId, Integer size) throws IOException {
        size = size == null ? 10 : size;
        agentId = (agentId != null && agentId <= 0) ? null : agentId;

        String timelineProductApi = String.format("%s/cwl/search/sort?pyq=true&size=%d", PRODUCT_HOST, size);
        String ret = OkHttpUtil.DEFAULT.get(timelineProductApi);
        return parseTimelineProduct(domain, domainId, agentId, ret);
    }

    @GetMapping("/search/forApp2")
    public Result searchProduct2(@PathVariable String domain, @PathVariable Long domainId, Integer agentId, String keyword, String type, Double price, Integer size) throws IOException {
        size = (size == null ? 20 : size);
        type = type == null ? "" : type;
        String url = "http://47.93.227.191:8181/cwl/search/internal?startid=" + 0 + "&size=" + size + "&keyword=" + (keyword == null ? "" : keyword) + "&type=" + type;
        url = url + "&pid=" + domain;
        agentId = (agentId != null && agentId <= 0) ? null : agentId;
        if (agentId != null) {
            url = url + "&sid=" + agentId;
        }
        if (price != null) {
            url = url + "&price=" + price;
        }

        String ret = OkHttpUtil.DEFAULT.get(url);
        logger.info("search request => {} response => {}", url, ret);
        return parseAndFormateProductRet2(domain, domainId, agentId, ret);
    }


    public Result parseAndFormateProductRet2(String domain, Long domainId, Integer agentId, String ret) throws IOException {
        List<ProductEntity> products = parseProductRetList(ret);


        Map<String, Object> config = globalConfigService.queryConfig(domainId);
        AgentEntity agent = null;
        if (agentId != null) {
            agent = agentService.getAgentById(Long.valueOf(agentId), domainId);
        }

        Map map = (Map) config.get("config");
        String couponUrl = "http://yhq.gittis.co";
        if (map != null && map.containsKey("couponUrl")) {
            couponUrl = (String) map.get("couponUrl");
        }

        // more = '%s/d/%s/p/%s/#' % (wxbot.config['coupon_url'], wxbot.domain, wxbot.agentId )
        String couponWebsite = couponUrl;
        if (agentId != null) {
            couponWebsite = String.format("%s/d/%s/p/%d/#", couponUrl, domain, agentId);
        }
        String couponWebsiteShortLink = innerAPIService.shortLink(couponWebsite);

        String template = (String) config.getOrDefault("template", Constants.PRODUCT_DEFAULT_TEMPLATE);
        logger.info("template => {}", template);

        List<Map> messages = new ArrayList<>();
        for (ProductEntity product : products) {
//            logger.info("taobaoApi.getTaokoulin: Link={}", product.getCouponLink());
//            String tkl = taobaoApi.getTaokoulinByCouponAndPid(domain, product.getCouponLink(), pid);
//            logger.info("[POST] /{}/api/third/tkls/translateLink tkl={}", domain, tkl);

            //  http://localhost:3000/#/detail/9667227/1/test
            String detailUrl = String.format("%s/#/detail/%d/%d/%s", couponUrl, product.getId(), agentId == null ? 0 : agentId, domain);
            String shortLink = innerAPIService.shortLink(detailUrl);

//            String product_template = ProductUtil.send_product_template(template, product, null, shortLink);
            Map productMap = new HashMap();

//            productMap.put("content", product_template);
            productMap.put("couponUrl", product.getCouponLink());
            productMap.put("couponSummarySite", couponWebsiteShortLink); // 汇总地址
            productMap.put("imageUrl", product.getItemImage());
            productMap.put("detailUrl", shortLink);
            productMap.put("intro", product.getIntro());
            productMap.put("price", product.getItemPrice());
            productMap.put("couponAmount", product.getCouponAmount());
            productMap.put("itemName", product.getItemName());

//            String template = (String) map.get("pyqHead");
            if (template.contains("{{汇总地址}}")) {
                template = template.replace("{{汇总地址}}", couponWebsiteShortLink);
            }
            if (template.contains("{{优惠链接}}")) {
                template = template.replace("{{优惠链接}}", couponWebsiteShortLink);
            }
            if (template.contains("{{详情地址}}")) {
                template = template.replace("{{详情地址}}", shortLink);
            }
            if (template.contains("{{详情链接}}")) {
                template = template.replace("{{详情链接}}", shortLink);
            }

            productMap.put("template", template);

            if (product.getDescImgs() != null) {
                productMap.put("descImgs", product.getDescImgs());
            } else {
                productMap.put("descImgs", Arrays.asList(product.getItemImage()));
            }

            // 计算佣金, commissionRate
            Integer itemRate = product.getItemRate();
            itemRate = itemRate == null || itemRate <= 0 ? 20 : itemRate;
            // agent
            Double price = product.getItemPrice();
            Double coupon = product.getCouponAmount();

            Double couponRate = (price - coupon) * 0.85 * itemRate / 100;
            if (agent != null && agent.getPerOfCommission() != null) {
                couponRate = couponRate * agent.getPerOfCommission() / 100;
                logger.info("coupon rate => {}", couponRate);
            } else {
                // 若是未登录的代理,则只能查看 0.45的佣金
                couponRate = couponRate * 0.45;
            }
            productMap.put("itemRate", itemRate);
            productMap.put("commissionRate", couponRate);

            productMap.put("nextTime", 55);     // next produt got time
            messages.add(productMap);
        }
        return wrapObj(messages);
    }

    public Result parseTimelineProduct(String domain, Long domainId, Integer agentId, String ret) throws IOException {
        Map retMap = GsonUtil.getObject(ret);
        if (retMap == null || !retMap.containsKey("success")) {
            throw new TBKException("request product center failed!");
        }
        Boolean success = (Boolean) retMap.get("success");
        if (!success) {
            throw new TBKException((String) retMap.get("message"));
        }
        List<Map> items = (List<Map>) retMap.get("data");


        Map<String, Object> config = globalConfigService.queryConfig(domainId);
        AgentEntity agent = null;
        if (agentId != null) {
            agent = agentService.getAgentById(Long.valueOf(agentId), domainId);
        }

        Map configMap = (Map) config.get("config");
        String couponUrl = "http://yhq.gittis.co";
        if (configMap != null && configMap.containsKey("couponUrl")) {
            couponUrl = (String) configMap.get("couponUrl");
        }
        // more = '%s/d/%s/p/%s/#' % (wxbot.config['coupon_url'], wxbot.domain, wxbot.agentId )
        String couponWebsite = couponUrl;
        if (agentId != null) {
            couponWebsite = String.format("%s/d/%s/p/%d/#", couponUrl, domain, agentId);
        }
        String couponWebsiteShortLink = innerAPIService.shortLink(couponWebsite);

        List<Map> products = new ArrayList<>();
        for (Map map : items) {
            HashMap product = new HashMap();

            product.put("itemName", map.get("title"));
            product.put("imageUrl", map.get("pic"));
            product.put("price", map.get("oldPrice"));
            product.put("couponAmount", map.get("couponMoney"));

            // 详情地址
            Double productId = (Double) map.get("id");
            String detailUrl = String.format("%s/#/detail/%d/%d/%s", couponUrl, productId.intValue(), agentId == null ? 0 : agentId, domain);
            String shortLink = innerAPIService.shortLink(detailUrl);
            product.put("detailUrl", shortLink);

            String template = (String) map.get("pyqHead");
//            if (template.contains("{{汇总地址}}")) {
//                template = template.replace("{{汇总地址}}", couponWebsiteShortLink);
//            }
//            if (template.contains("{{优惠链接}}")) {
//                template = template.replace("{{优惠链接}}", couponWebsiteShortLink);
//            }
//            if (template.contains("{{详情地址}}")) {
//                template = template.replace("{{详情地址}}", shortLink);
//            }
//            if (template.contains("{{详情链接}}")) {
//                template = template.replace("{{详情链接}}", shortLink);
//            }

            product.put("template", template);
            product.put("pyq_comment", map.get("pyqComment"));
            product.put("couponUrl", map.get("couponUrl"));
            product.put("intro", map.get("description"));

            // 汇总地址
            product.put("couponSummarySite", couponWebsiteShortLink);
            product.put("descImgs", map.get("pyqImgArray"));

            // 计算佣金, commissionRate
            // calculate commissionRate
            Double itemRate = (Double) map.get("commissionRate");
            itemRate = itemRate == null || itemRate <= 0 ? 30 : itemRate;
            // agent
            Double price = (Double) map.get("oldPrice");
            Double coupon = (Double) map.get("couponMoney");

            if (price == null || coupon == null) {
                continue;
            }

            Double couponRate = (price - coupon) * 0.85 * itemRate / 100;
            if (agent != null && agent.getPerOfCommission() != null) {
                couponRate = couponRate * agent.getPerOfCommission() / 100;
                logger.info("coupon rate => {}", couponRate);
            } else {
                // 若是未登录的代理,则只能查看 0.45的佣金
                couponRate = couponRate * 0.45;
            }
            product.put("itemRate", itemRate);
            product.put("commissionRate", couponRate);
            product.put("nextTime", 55);     // next produt got time
            products.add(product);
        }
        return wrapObj(products);
    }


    private final
    @NonNull
    ProductService productService;

    private final
    @NonNull
    InnerAPIService innerAPIService;

    private final
    @NonNull
    AgentService agentService;


    private final
    @NonNull
    PIDService pidService;

    private final
    @NonNull
    TaobaoApi taobaoApi;


    private final
    @NonNull
    GlobalConfigService globalConfigService;


    private static Logger logger = LogManager.getLogger(ProductController.class);
}
